# app/utils/file_handlers.py
import os
import uuid
from fastapi import UploadFile, HTTPException
from typing import Dict, Any
import shutil
from pathlib import Path
from app.config import STATIC_DIR, FILE_UPLOAD_CONFIG


async def save_upload_file(upload_file: UploadFile, file_type: str) -> Dict[str, Any]:
    """
    通用文件上传函数

    参数:
    - upload_file: 上传的文件对象
    - file_type: 文件类型（对应FILE_UPLOAD_CONFIG中的键）

    返回:
    - 包含文件信息的字典
    """
    # 检查文件类型配置是否存在
    if file_type not in FILE_UPLOAD_CONFIG:
        raise HTTPException(
            status_code=400,
            detail=f"不支持的文件类型: {file_type}"
        )

    config = FILE_UPLOAD_CONFIG[file_type]

    # 检查文件类型
    if upload_file.content_type not in config["allowed_types"]:
        raise HTTPException(
            status_code=400,
            detail=f"不支持的文件类型: {upload_file.content_type}. 请上传: {', '.join(config['allowed_types'])}"
        )

    # 读取文件内容以检查大小
    contents = await upload_file.read()

    # 检查文件大小
    if len(contents) > config["max_size"]:
        raise HTTPException(
            status_code=400,
            detail=f"文件太大: {len(contents)} bytes. 最大允许: {config['max_size']} bytes"
        )

    # 生成唯一文件名
    file_extension = upload_file.filename.split(".")[-1] if "." in upload_file.filename else ""
    filename = f"{uuid.uuid4().hex}.{file_extension}" if file_extension else f"{uuid.uuid4().hex}"

    # 确定保存路径
    save_dir = STATIC_DIR / config["subfolder"]
    save_path = save_dir / filename

    # 确保目录存在
    os.makedirs(save_dir, exist_ok=True)

    # 保存文件
    with open(save_path, "wb") as buffer:
        # 重置文件指针并写入
        await upload_file.seek(0)
        shutil.copyfileobj(upload_file.file, buffer)

    # 构建返回数据
    relative_path = f"{config['subfolder']}/{filename}"
    full_url = f"/static/{relative_path}"

    return {
        "filename": filename,
        "file_path": relative_path,
        "file_url": full_url,
        "file_type": upload_file.content_type,
        "file_size": len(contents)
    }


async def delete_file(file_path: str) -> bool:
    """
    删除文件

    参数:
    - file_path: 相对路径（如 "coffee_products/filename.jpg"）

    返回:
    - 是否成功删除
    """
    full_path = STATIC_DIR / file_path
    if os.path.exists(full_path):
        os.remove(full_path)
        return True
    return False


async def get_file_info(file_path: str) -> Dict[str, Any]:
    """
    获取文件信息

    参数:
    - file_path: 相对路径

    返回:
    - 文件信息字典
    """
    full_path = STATIC_DIR / file_path
    if not os.path.exists(full_path):
        return None

    return {
        "filename": os.path.basename(file_path),
        "file_path": file_path,
        "file_url": f"/static/{file_path}",
        "file_size": os.path.getsize(full_path),
        "last_modified": os.path.getmtime(full_path)
    }